package com.spi.soconversion.base.definition;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

import com.spi.soconversion.base.SOCException;
import com.spi.soconversion.base.handlers.ClosedSalesConversionStatisticsHandler;
import com.spi.soconversion.orders.SOCChargeNames;
import com.spi.soconversion.util.SOCConstants;
import com.spi.soconversion.util.XMLTagConstants;

public class SOCOrderLines {

	private List<SOCOrderLine> orderLinesList = new ArrayList<SOCOrderLine>();
	private List<SOCOrderLineSalvage> salvageorderLinesList = new ArrayList<SOCOrderLineSalvage>();
	private List<String>  furnitureCategories ;
	private long orderNum;
	private ClosedSalesConversionStatisticsHandler statisticsHandler;
	private int batchNum;
	private String wrfeeCategories[]= {"501", "502", "504", "505", "506", "507", "508", "509", "510", "513", "514", "517", "518", "519", "520", "521", "522"};
	public SOCOrderLines(long orderNumber,ClosedSalesConversionStatisticsHandler statisticsHandler,int batchNum)
	{
		this.orderNum=orderNumber;
		this.statisticsHandler=statisticsHandler;
		this.batchNum=batchNum;
		// populate furniture warranty categories
		furnitureCategories=(List) Arrays.asList(wrfeeCategories);
	}
	public SOCOrderLines()
	{
		
	}
	private int lineNum =1;
	public boolean addOrderLine(SOCOrderLine on){
		boolean status = false;
		if(!orderLinesList.contains(on)) {
			status = orderLinesList.add(on);
		}

		return status;
	}

	public boolean addSalvageOrderLine(SOCOrderLineSalvage on){
		boolean status = false;
		if(!salvageorderLinesList.contains(on)) {
			status = salvageorderLinesList.add(on);
		}

		return status;
	}

	public void removeOrderLineList(List<SOCOrderLine> on){
		if(on!=null && on.size()>0)
		{	
			Iterator<SOCOrderLine> iter=on.iterator();
			while(iter.hasNext())
			{
				SOCOrderLine line = iter.next();
				orderLinesList.remove(line);
			}
		}
	}
	
	public void removeOrderLine(SOCOrderLine line){
		if(line!=null )
		{	
			orderLinesList.remove(line);
		}
	}

	public void removeSalvageOrderLineList(List<SOCOrderLineSalvage> on){
		if(on!=null && on.size()>0)
		{	
			Iterator<SOCOrderLineSalvage> iter=on.iterator();
			while(iter.hasNext())
			{
				SOCOrderLineSalvage line = iter.next();
				salvageorderLinesList.remove(line);
			}
		}
	}

	public List<SOCOrderLine> getOrderLineList(){
		return orderLinesList;		
	}

	public void filterOrderLineList(){
		List<SOCOrderLine> donotConvertLinesList = new ArrayList<SOCOrderLine>();
		if(orderLinesList!=null && orderLinesList.size()>0)
		{	
			Iterator<SOCOrderLine> iter=orderLinesList.iterator();
			while(iter.hasNext())
			{
				SOCOrderLine line = iter.next();

				if(line.getIsReturned() || !SOCConstants.CLOSED.equals(line.getStatus()))
				{
					donotConvertLinesList.add(line);
				}    		
			}
			removeOrderLineList(donotConvertLinesList);
		}
	}

	@Override
	public String toString()
	{
		StringBuilder sb = new StringBuilder();

		if(orderLinesList!=null && orderLinesList.size()>0)
		{
			sb.append(XMLTagConstants.START_TAG_ORDER_LINES);
			Iterator<SOCOrderLine> iter=orderLinesList.iterator();
			while(iter.hasNext())
			{
				SOCOrderLine line = iter.next();
				line.setPrimeLineNo(lineNum++);
				sb.append(SOCConstants.NEW_LINE);
				sb.append(line.toString());	    		    		
			}
			sb.append(SOCConstants.NEW_LINE);
			sb.append(XMLTagConstants.END_TAG_ORDER_LINES);

		}

		return sb.toString();
	}

	public void filterSalvageOrderLineList(){
		List<SOCOrderLineSalvage> donotConvertLinesList = new ArrayList<SOCOrderLineSalvage>();
		if(salvageorderLinesList!=null && salvageorderLinesList.size()>0)
		{	
			Iterator<SOCOrderLineSalvage> iter=salvageorderLinesList.iterator();
			while(iter.hasNext())
			{
				SOCOrderLineSalvage line = iter.next();
				if(line.getIsReturned() || !SOCConstants.CLOSED.equals(line.getStatus()))
				{
					donotConvertLinesList.add(line);
				}    		
			}
			removeSalvageOrderLineList(donotConvertLinesList);
		}
	}

	public List<SOCOrderLineSalvage> getSalvageOrderLines(){
		return salvageorderLinesList;		
	}

	public void attachSalvageWithDelivery() throws SOCException{
		SOCOrderLineSalvage orderLineSalvage = null;
		SOCOrderLineTax orderLineSalvageTax = null;
		SOCOrderLine deliveryLine = null;
		if(orderLinesList!=null && orderLinesList.size()>0)
		{
			Iterator<SOCOrderLine> iter=orderLinesList.iterator();
			while(iter.hasNext())
			{
				SOCOrderLine line = iter.next();
				String itemType = line.getLineItemType();
				if("DEL".equals(itemType))
				{
					deliveryLine =  line;
					break;
				}
			}
		}
		if(salvageorderLinesList!=null && salvageorderLinesList.size()>0)
		{	
				if(deliveryLine!=null){				
				orderLineSalvage = new SOCOrderLineSalvage();
				orderLineSalvageTax = null;
				SOCOrderLineTaxes lineTaxes = deliveryLine.getLineTaxes();
				String optServiceSKU= null;	
				orderLineSalvage.setUnitOfMeasure(SOCConstants.MIN);
				boolean isHSTEligible = false;
				BigDecimal totUnitPrice = new BigDecimal("0");
				BigDecimal totHst = new BigDecimal("0");
				BigDecimal totGst = new BigDecimal("0");
				BigDecimal totPst = new BigDecimal("0");

				BigDecimal hstTaxPercentage = new BigDecimal("0");
				BigDecimal pstTaxPercentage = new BigDecimal("0");
				BigDecimal gstTaxPercentage = new BigDecimal("0");

				Iterator<SOCOrderLineSalvage> iter=salvageorderLinesList.iterator();
				while(iter.hasNext())
				{
					SOCOrderLineSalvage line = iter.next();

					orderLineSalvage.setItemDesc(line.getItemDesc());
					orderLineSalvage.setItemID(line.getItemID());
					optServiceSKU=line.getItemID();
					totUnitPrice = totUnitPrice.add(line.getUnitPrice());	
					
					if(!isHSTEligible)
					{
						isHSTEligible=line.getIsHSTEligible();
					}
					totHst = totHst.add(line.getHstTax());
					totGst = totGst.add(line.getGstTax());
					totPst = totPst.add(line.getPstTax());
					if(hstTaxPercentage.compareTo(new BigDecimal("0"))==0)
					{
						hstTaxPercentage = line.getHstTaxPercentage();
					}
					if(pstTaxPercentage.compareTo(new BigDecimal("0"))==0)
					{
						pstTaxPercentage = line.getPstTaxPercentage();
					}
					if(gstTaxPercentage.compareTo(new BigDecimal("0"))==0)
					{
						gstTaxPercentage = line.getGstTaxPercentage();
					}
				}   
				
				orderLineSalvage.setUnitPrice(totUnitPrice);
				deliveryLine.setOrderLineSalvage(orderLineSalvage);
				
				BigDecimal totTax = new BigDecimal("0");
				BigDecimal taxPercentage = new BigDecimal("0");
				if(totHst.compareTo(new BigDecimal("0"))==1 || isHSTEligible)
				{
					orderLineSalvageTax = new SOCOrderLineTax();
					totTax=totTax.add(totHst);
					
					if(totPst.compareTo(new BigDecimal("0"))==1)
					{
						totTax=totTax.add(totPst);
					}
					if(totGst.compareTo(new BigDecimal("0"))==1)
					{
						totTax=totTax.add(totGst);
					}
					if(hstTaxPercentage.compareTo(new BigDecimal("0"))==1 )
					{
						taxPercentage=taxPercentage.add(hstTaxPercentage);
					}
					else
					{
						taxPercentage=taxPercentage.add(pstTaxPercentage).add(gstTaxPercentage);
					}
										
					orderLineSalvageTax.setChargeCategory(SOCConstants.EMPTY_STRING);
					orderLineSalvageTax.setChargeName(SOCChargeNames.getSVGChargeName(optServiceSKU));
					orderLineSalvageTax.setTaxName(SOCConstants.TAX_NAME_OPT_HST);
					orderLineSalvageTax.setTaxAmount(totTax);
					orderLineSalvageTax.setTaxPercentage(taxPercentage.toString());
					
					lineTaxes.addLineTax(orderLineSalvageTax);
				}
				else
				{
					if(totGst.compareTo(new BigDecimal("0"))==1)
					{
						orderLineSalvageTax = new SOCOrderLineTax();

						orderLineSalvageTax.setChargeCategory(SOCConstants.EMPTY_STRING);
						orderLineSalvageTax.setChargeName(SOCChargeNames.getSVGChargeName(optServiceSKU));
						orderLineSalvageTax.setTaxAmount(totGst);
						orderLineSalvageTax.setTaxPercentage(gstTaxPercentage.toString());
						orderLineSalvageTax.setTaxName(SOCConstants.TAX_NAME_OPT_GST);    	
						
						lineTaxes.addLineTax(orderLineSalvageTax);
					}

					if(totPst.compareTo(new BigDecimal("0"))==1)
					{
						orderLineSalvageTax = new SOCOrderLineTax();

						orderLineSalvageTax.setChargeCategory(SOCConstants.EMPTY_STRING);
						orderLineSalvageTax.setChargeName(SOCChargeNames.getSVGChargeName(optServiceSKU));
						orderLineSalvageTax.setTaxAmount(totPst);
						orderLineSalvageTax.setTaxPercentage(pstTaxPercentage.toString());
						orderLineSalvageTax.setTaxName(SOCConstants.TAX_NAME_OPT_PST);   
						
						lineTaxes.addLineTax(orderLineSalvageTax);
					}					
				}
				deliveryLine.setLineTotal();
			}
			else
			{
				statisticsHandler.addMessages(orderNum, batchNum, SOCConstants.WARNING, SOCConstants.MESSAGE_PROCESSING_CLOSED_ORDER_WITH_NO_DELIVERY_LINE_FOR_SVG, ""+0);
			}
		}
	}
	
	public void filterWTYOrderLines() throws SOCException{
		List<SOCOrderLine> nonFurnitureWtyLinesList = new ArrayList<SOCOrderLine>();
		List<SOCOrderLine> furnitureWtyLinesList = new ArrayList<SOCOrderLine>();
		List<SOCOrderLine> furnitureWRFEELinesList = new ArrayList<SOCOrderLine>();
		HashMap<String,SOCOrderLine> linesMap = new HashMap<String,SOCOrderLine>();
		if(orderLinesList!=null && orderLinesList.size()>0)
		{	
			Iterator<SOCOrderLine> iter=orderLinesList.iterator();
			while(iter.hasNext())
			{
				SOCOrderLine line = iter.next();
				String itemType = line.getLineItemType();
				
				BigDecimal unitListPrice = line.getUnitListPrice();
				String serviceRefLineId = line.getServiceRefId();
				if("WTY".equals(itemType))
				{
					if(serviceRefLineId!=null)
					{
						SOCOrderLine primeLine = linesMap.get(serviceRefLineId);
						if(primeLine!=null)
						{
							if(!furnitureCategories.contains(primeLine.getItemCategory()))
							{
								
								nonFurnitureWtyLinesList.add(line);
							}
							else
							{
								furnitureWtyLinesList.add(line);							
							}
						}
						
					}
					else
					{
						statisticsHandler.addMessages(orderNum, batchNum, SOCConstants.WARNING, SOCConstants.MESSAGE_PROCESSING_CLOSED_ORDER_WTY_WITH_NO_SALES_LINE,line.getLineId());
					}
				}
				else if("WRFEE".equals(itemType))
				{
					furnitureWRFEELinesList.add(line);
				}
				
				linesMap.put(line.getLineId(),line);
			}
			String warrantyFeeSKU  = null;
			if(furnitureWRFEELinesList!=null && furnitureWRFEELinesList.size()>0)
			{
				SOCOrderLine wrfeeLine = furnitureWRFEELinesList.get(0);
				SOCOrderLineItem wrfeeLineItem = wrfeeLine.getLineItem();			
				if(wrfeeLineItem!=null)
				{
					warrantyFeeSKU = wrfeeLineItem.getItemID();
				}
			}
			
			if(furnitureWtyLinesList!=null && furnitureWtyLinesList.size()>0)
			{
				Iterator<SOCOrderLine> iterFurniture=furnitureWtyLinesList.iterator();
				while(iterFurniture.hasNext())
				{
					SOCOrderLine line = iterFurniture.next();
					String serviceRefLineId = line.getServiceRefId();
					
					if(serviceRefLineId!=null)
					{
						SOCOrderLine itemLine = linesMap.get(serviceRefLineId);
						String lineCategory = null;
						if(itemLine!=null)
						{
							lineCategory=itemLine.getLineCategory();
							//if(lineCategory!=null && FurnitureCategory.getFurnitureCategory(lineCategory)!=null)
						//	{
								SOCOrderLineExtn itemLineExtn = itemLine.getLineExtn();
								if(itemLineExtn!=null)
								{
									itemLineExtn.setExtnWarrantySku(warrantyFeeSKU);
									removeOrderLine(line);
								}
							//}								
							//else
							//{
								// to do error handling
							//}							
						}
						else
						{
							removeOrderLine(line);
							statisticsHandler.addMessages(orderNum, batchNum, SOCConstants.WARNING, SOCConstants.MESSAGE_PROCESSING_CLOSED_ORDER_FURNITURE_WTY_WITH_SALES_LINE_NOT_ON_ORDER, line.getLineId());
						}
					}
					else
					{
						removeOrderLine(line);
						statisticsHandler.addMessages(orderNum, batchNum, SOCConstants.WARNING, SOCConstants.MESSAGE_PROCESSING_CLOSED_ORDER_FURNITURE_WTY_WITH_NO_SALES_LINE, line.getLineId());
					}
				}
			}
			
			if(nonFurnitureWtyLinesList!=null && nonFurnitureWtyLinesList.size()>0)
			{
				Iterator<SOCOrderLine> iterNonFurniture=nonFurnitureWtyLinesList.iterator();
				while(iterNonFurniture.hasNext())
				{
					SOCOrderLine line = iterNonFurniture.next();
					String serviceRefLineId = line.getServiceRefId();
					
					if(serviceRefLineId!=null)
					{
						SOCOrderLine itemLine = linesMap.get(serviceRefLineId);
						
						if(itemLine!=null)
						{
							SOCOrderLineItem wtyLineItem = line.getLineItem();
							String warrantySKU  = null;
							if(wtyLineItem!=null)
							{
								warrantySKU = wtyLineItem.getItemID();
							}
							else
							{
								// to do error handling
							}
							
							SOCOrderLineExtn itemLineExtn = itemLine.getLineExtn();
							if(itemLineExtn!=null)
							{
								itemLineExtn.setExtnWarrantySku(warrantySKU);
							}
							else
							{
								// to do error handling
							}
						}
						else
						{
							statisticsHandler.addMessages(orderNum, batchNum, SOCConstants.WARNING, SOCConstants.MESSAGE_PROCESSING_CLOSED_ORDER_WTY_WITH_SALES_LINE_NOT_ON_ORDER, line.getLineId());
						}
					}
					else
					{
						statisticsHandler.addMessages(orderNum, batchNum, SOCConstants.WARNING, SOCConstants.MESSAGE_PROCESSING_CLOSED_ORDER_WTY_WITH_NO_SALES_LINE, line.getLineId());
					}
				}
			}
			
		}
	}
}
